
import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.Props

case class Work(start : Long, end : Long, length : Long);
case class Stop();
case class Done();

class Manager extends Actor {
  
  var doneCount = 0
  var workers = Runtime.getRuntime().availableProcessors();
  
  def receive = {
    case Work(start, end, length) => 
      {
	    val workSize = (end / workers);
	    
	    for (i <- 0 to workers - 1)
	    {
	      val w = context.system.actorOf(Props[Worker], name = "w" + i)
	      if (i == 0)
	      {
	    	w ! Work(1, workSize, length)
	      }
		  else if (i == workers - 1)
		  {
		    w ! Work(((workSize * i) + 1), end, length)
		  }
	      else 
	      {
	        w ! Work(((workSize * i) + 1), (workSize * (i + 1)), length)
	      }
	    }
      }
    case Done =>
      {
        doneCount = doneCount + 1
        if (doneCount == workers)
        {
          context.system.shutdown()
        }
      }
  }
}

class Worker extends Actor {
  def receive = {
    case Work(start, end, length) => 
      {
        var i = start
        while (i <= end)
        {
		    var sum : Long = 0;
		    var j = i;
		    while (j < (i + length))
		    {
		      sum = sum + (j * j)
		      j = j + 1;
		    }
		       
		    val result = Math.sqrt(sum).toLong
		    val sum2 = result * result 
		     
		    if (sum == sum2)
		    {
		      println(i);
		    }
		    
		    i = i + 1
		}
        sender ! Done;
      }
  }
}

object Main extends App {
  val system = ActorSystem("System")
  val mgr = system.actorOf(Props[Manager], name = "mgr")
  //val startTime = System.currentTimeMillis();
  mgr ! Work("1".toLong, args(0).toLong, args(1).toLong)

  system.awaitTermination()
  
  //val endTime   = System.currentTimeMillis()
  //val totalTime = (endTime - startTime)
  //println("Time: " + totalTime + " ms")
}